
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>pymatgen.util.coord &#8212; pymatgen 2020.7.3 documentation</title>
    <link rel="stylesheet" href="../../../_static/basic.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../_static/language_data.js"></script>
    <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
 
<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-33990148-1']);
  _gaq.push(['_trackPageview']);
</script>

  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" accesskey="U">pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.util.coord</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
          <div class="body" role="main">
            
  <h1>Source code for pymatgen.util.coord</h1><div class="highlight"><pre>
<span></span><span class="c1"># coding: utf-8</span>
<span class="c1"># Copyright (c) Pymatgen Development Team.</span>
<span class="c1"># Distributed under the terms of the MIT License.</span>


<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Utilities for manipulating coordinates or list of coordinates, under periodic</span>
<span class="sd">boundary conditions or otherwise. Many of these are heavily vectorized in</span>
<span class="sd">numpy for performance.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">itertools</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">math</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">coord_cython</span> <span class="k">as</span> <span class="n">cuc</span>


<span class="n">__author__</span> <span class="o">=</span> <span class="s2">&quot;Shyue Ping Ong&quot;</span>
<span class="n">__copyright__</span> <span class="o">=</span> <span class="s2">&quot;Copyright 2011, The Materials Project&quot;</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;1.0&quot;</span>
<span class="n">__maintainer__</span> <span class="o">=</span> <span class="s2">&quot;Shyue Ping Ong&quot;</span>
<span class="n">__email__</span> <span class="o">=</span> <span class="s2">&quot;shyuep@gmail.com&quot;</span>
<span class="n">__date__</span> <span class="o">=</span> <span class="s2">&quot;Nov 27, 2011&quot;</span>

<span class="c1"># array size threshold for looping instead of broadcasting</span>
<span class="n">LOOP_THRESHOLD</span> <span class="o">=</span> <span class="mf">1e6</span>


<div class="viewcode-block" id="find_in_coord_list"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.find_in_coord_list">[docs]</a><span class="k">def</span> <span class="nf">find_in_coord_list</span><span class="p">(</span><span class="n">coord_list</span><span class="p">,</span> <span class="n">coord</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Find the indices of matches of a particular coord in a coord_list.</span>

<span class="sd">    Args:</span>
<span class="sd">        coord_list: List of coords to test</span>
<span class="sd">        coord: Specific coordinates</span>
<span class="sd">        atol: Absolute tolerance. Defaults to 1e-8. Accepts both scalar and</span>
<span class="sd">            array.</span>

<span class="sd">    Returns:</span>
<span class="sd">        Indices of matches, e.g., [0, 1, 2, 3]. Empty list if not found.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">coord_list</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">[]</span>
    <span class="n">diff</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">coord_list</span><span class="p">)</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">coord</span><span class="p">)[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:]</span>
    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">diff</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">atol</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span></div>


<div class="viewcode-block" id="in_coord_list"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.in_coord_list">[docs]</a><span class="k">def</span> <span class="nf">in_coord_list</span><span class="p">(</span><span class="n">coord_list</span><span class="p">,</span> <span class="n">coord</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Tests if a particular coord is within a coord_list.</span>

<span class="sd">    Args:</span>
<span class="sd">        coord_list: List of coords to test</span>
<span class="sd">        coord: Specific coordinates</span>
<span class="sd">        atol: Absolute tolerance. Defaults to 1e-8. Accepts both scalar and</span>
<span class="sd">            array.</span>

<span class="sd">    Returns:</span>
<span class="sd">        True if coord is in the coord list.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_in_coord_list</span><span class="p">(</span><span class="n">coord_list</span><span class="p">,</span> <span class="n">coord</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="n">atol</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">0</span></div>


<div class="viewcode-block" id="is_coord_subset"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.is_coord_subset">[docs]</a><span class="k">def</span> <span class="nf">is_coord_subset</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">superset</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Tests if all coords in subset are contained in superset.</span>
<span class="sd">    Doesn&#39;t use periodic boundary conditions</span>

<span class="sd">    Args:</span>
<span class="sd">        subset, superset: List of coords</span>

<span class="sd">    Returns:</span>
<span class="sd">        True if all of subset is in superset.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">c1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">subset</span><span class="p">)</span>
    <span class="n">c2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">superset</span><span class="p">)</span>
    <span class="n">is_close</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">c1</span><span class="p">[:,</span> <span class="kc">None</span><span class="p">,</span> <span class="p">:]</span> <span class="o">-</span> <span class="n">c2</span><span class="p">[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:,</span> <span class="p">:])</span> <span class="o">&lt;</span> <span class="n">atol</span><span class="p">,</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">any_close</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">is_close</span><span class="p">,</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">any_close</span><span class="p">)</span></div>


<div class="viewcode-block" id="coord_list_mapping"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.coord_list_mapping">[docs]</a><span class="k">def</span> <span class="nf">coord_list_mapping</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">superset</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Gives the index mapping from a subset to a superset.</span>
<span class="sd">    Subset and superset cannot contain duplicate rows</span>

<span class="sd">    Args:</span>
<span class="sd">        subset, superset: List of coords</span>

<span class="sd">    Returns:</span>
<span class="sd">        list of indices such that superset[indices] = subset</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">c1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">subset</span><span class="p">)</span>
    <span class="n">c2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">superset</span><span class="p">)</span>
    <span class="n">inds</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">isclose</span><span class="p">(</span><span class="n">c1</span><span class="p">[:,</span> <span class="kc">None</span><span class="p">,</span> <span class="p">:],</span> <span class="n">c2</span><span class="p">[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:,</span> <span class="p">:],</span> <span class="n">atol</span><span class="o">=</span><span class="n">atol</span><span class="p">),</span>
                           <span class="n">axis</span><span class="o">=</span><span class="mi">2</span><span class="p">))[</span><span class="mi">1</span><span class="p">]</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">c2</span><span class="p">[</span><span class="n">inds</span><span class="p">]</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">np</span><span class="o">.</span><span class="n">allclose</span><span class="p">(</span><span class="n">c1</span><span class="p">,</span> <span class="n">result</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="n">atol</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">is_coord_subset</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">superset</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;subset is not a subset of superset&quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">shape</span> <span class="o">==</span> <span class="n">c1</span><span class="o">.</span><span class="n">shape</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Something wrong with the inputs, likely duplicates &quot;</span>
                         <span class="s2">&quot;in superset&quot;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">inds</span></div>


<div class="viewcode-block" id="coord_list_mapping_pbc"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.coord_list_mapping_pbc">[docs]</a><span class="k">def</span> <span class="nf">coord_list_mapping_pbc</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">superset</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Gives the index mapping from a subset to a superset.</span>
<span class="sd">    Superset cannot contain duplicate matching rows</span>

<span class="sd">    Args:</span>
<span class="sd">        subset, superset: List of frac_coords</span>

<span class="sd">    Returns:</span>
<span class="sd">        list of indices such that superset[indices] = subset</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">atol</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mf">1.</span><span class="p">,</span> <span class="mf">1.</span><span class="p">,</span> <span class="mf">1.</span><span class="p">])</span> <span class="o">*</span> <span class="n">atol</span>
    <span class="k">return</span> <span class="n">cuc</span><span class="o">.</span><span class="n">coord_list_mapping_pbc</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">superset</span><span class="p">,</span> <span class="n">atol</span><span class="p">)</span></div>


<div class="viewcode-block" id="get_linear_interpolated_value"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.get_linear_interpolated_value">[docs]</a><span class="k">def</span> <span class="nf">get_linear_interpolated_value</span><span class="p">(</span><span class="n">x_values</span><span class="p">,</span> <span class="n">y_values</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns an interpolated value by linear interpolation between two values.</span>
<span class="sd">    This method is written to avoid dependency on scipy, which causes issues on</span>
<span class="sd">    threading servers.</span>

<span class="sd">    Args:</span>
<span class="sd">        x_values: Sequence of x values.</span>
<span class="sd">        y_values: Corresponding sequence of y values</span>
<span class="sd">        x: Get value at particular x</span>

<span class="sd">    Returns:</span>
<span class="sd">        Value at x.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">x_values</span><span class="p">,</span> <span class="n">y_values</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">d</span><span class="p">:</span> <span class="n">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>

    <span class="n">ind</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">a</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">x</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>

    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">ind</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">ind</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;x is out of range of provided x_values&quot;</span><span class="p">)</span>

    <span class="n">i</span> <span class="o">=</span> <span class="n">ind</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="n">x1</span><span class="p">,</span> <span class="n">x2</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
    <span class="n">y1</span><span class="p">,</span> <span class="n">y2</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>

    <span class="k">return</span> <span class="n">y1</span> <span class="o">+</span> <span class="p">(</span><span class="n">y2</span> <span class="o">-</span> <span class="n">y1</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">x2</span> <span class="o">-</span> <span class="n">x1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">x1</span><span class="p">)</span></div>


<div class="viewcode-block" id="all_distances"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.all_distances">[docs]</a><span class="k">def</span> <span class="nf">all_distances</span><span class="p">(</span><span class="n">coords1</span><span class="p">,</span> <span class="n">coords2</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns the distances between two lists of coordinates</span>

<span class="sd">    Args:</span>
<span class="sd">        coords1: First set of cartesian coordinates.</span>
<span class="sd">        coords2: Second set of cartesian coordinates.</span>

<span class="sd">    Returns:</span>
<span class="sd">        2d array of cartesian distances. E.g the distance between</span>
<span class="sd">        coords1[i] and coords2[j] is distances[i,j]</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">c1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">coords1</span><span class="p">)</span>
    <span class="n">c2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">coords2</span><span class="p">)</span>
    <span class="n">z</span> <span class="o">=</span> <span class="p">(</span><span class="n">c1</span><span class="p">[:,</span> <span class="kc">None</span><span class="p">,</span> <span class="p">:]</span> <span class="o">-</span> <span class="n">c2</span><span class="p">[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:,</span> <span class="p">:])</span> <span class="o">**</span> <span class="mi">2</span>
    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">z</span><span class="p">,</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span> <span class="o">**</span> <span class="mf">0.5</span></div>


<div class="viewcode-block" id="pbc_diff"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.pbc_diff">[docs]</a><span class="k">def</span> <span class="nf">pbc_diff</span><span class="p">(</span><span class="n">fcoords1</span><span class="p">,</span> <span class="n">fcoords2</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns the &#39;fractional distance&#39; between two coordinates taking into</span>
<span class="sd">    account periodic boundary conditions.</span>

<span class="sd">    Args:</span>
<span class="sd">        fcoords1: First set of fractional coordinates. e.g., [0.5, 0.6,</span>
<span class="sd">            0.7] or [[1.1, 1.2, 4.3], [0.5, 0.6, 0.7]]. It can be a single</span>
<span class="sd">            coord or any array of coords.</span>
<span class="sd">        fcoords2: Second set of fractional coordinates.</span>

<span class="sd">    Returns:</span>
<span class="sd">        Fractional distance. Each coordinate must have the property that</span>
<span class="sd">        abs(a) &lt;= 0.5. Examples:</span>
<span class="sd">        pbc_diff([0.1, 0.1, 0.1], [0.3, 0.5, 0.9]) = [-0.2, -0.4, 0.2]</span>
<span class="sd">        pbc_diff([0.9, 0.1, 1.01], [0.3, 0.5, 0.9]) = [-0.4, -0.4, 0.11]</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">fdist</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">subtract</span><span class="p">(</span><span class="n">fcoords1</span><span class="p">,</span> <span class="n">fcoords2</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">fdist</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">round</span><span class="p">(</span><span class="n">fdist</span><span class="p">)</span></div>


<div class="viewcode-block" id="pbc_shortest_vectors"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.pbc_shortest_vectors">[docs]</a><span class="k">def</span> <span class="nf">pbc_shortest_vectors</span><span class="p">(</span><span class="n">lattice</span><span class="p">,</span> <span class="n">fcoords1</span><span class="p">,</span> <span class="n">fcoords2</span><span class="p">,</span> <span class="n">mask</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                         <span class="n">return_d2</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns the shortest vectors between two lists of coordinates taking into</span>
<span class="sd">    account periodic boundary conditions and the lattice.</span>

<span class="sd">    Args:</span>
<span class="sd">        lattice: lattice to use</span>
<span class="sd">        fcoords1: First set of fractional coordinates. e.g., [0.5, 0.6, 0.7]</span>
<span class="sd">            or [[1.1, 1.2, 4.3], [0.5, 0.6, 0.7]]. It can be a single</span>
<span class="sd">            coord or any array of coords.</span>
<span class="sd">        fcoords2: Second set of fractional coordinates.</span>
<span class="sd">        mask (boolean array): Mask of matches that are not allowed.</span>
<span class="sd">            i.e. if mask[1,2] == True, then subset[1] cannot be matched</span>
<span class="sd">            to superset[2]</span>
<span class="sd">        return_d2 (boolean): whether to also return the squared distances</span>

<span class="sd">    Returns:</span>
<span class="sd">        array of displacement vectors from fcoords1 to fcoords2</span>
<span class="sd">        first index is fcoords1 index, second is fcoords2 index</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">cuc</span><span class="o">.</span><span class="n">pbc_shortest_vectors</span><span class="p">(</span><span class="n">lattice</span><span class="p">,</span> <span class="n">fcoords1</span><span class="p">,</span> <span class="n">fcoords2</span><span class="p">,</span> <span class="n">mask</span><span class="p">,</span>
                                    <span class="n">return_d2</span><span class="p">)</span></div>


<div class="viewcode-block" id="find_in_coord_list_pbc"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.find_in_coord_list_pbc">[docs]</a><span class="k">def</span> <span class="nf">find_in_coord_list_pbc</span><span class="p">(</span><span class="n">fcoord_list</span><span class="p">,</span> <span class="n">fcoord</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Get the indices of all points in a fractional coord list that are</span>
<span class="sd">    equal to a fractional coord (with a tolerance), taking into account</span>
<span class="sd">    periodic boundary conditions.</span>

<span class="sd">    Args:</span>
<span class="sd">        fcoord_list: List of fractional coords</span>
<span class="sd">        fcoord: A specific fractional coord to test.</span>
<span class="sd">        atol: Absolute tolerance. Defaults to 1e-8.</span>

<span class="sd">    Returns:</span>
<span class="sd">        Indices of matches, e.g., [0, 1, 2, 3]. Empty list if not found.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">fcoord_list</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">[]</span>
    <span class="n">fcoords</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">fcoord</span><span class="p">,</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">fcoord_list</span><span class="p">),</span> <span class="mi">1</span><span class="p">))</span>
    <span class="n">fdist</span> <span class="o">=</span> <span class="n">fcoord_list</span> <span class="o">-</span> <span class="n">fcoords</span>
    <span class="n">fdist</span> <span class="o">-=</span> <span class="n">np</span><span class="o">.</span><span class="n">round</span><span class="p">(</span><span class="n">fdist</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">fdist</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">atol</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span></div>


<div class="viewcode-block" id="in_coord_list_pbc"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.in_coord_list_pbc">[docs]</a><span class="k">def</span> <span class="nf">in_coord_list_pbc</span><span class="p">(</span><span class="n">fcoord_list</span><span class="p">,</span> <span class="n">fcoord</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Tests if a particular fractional coord is within a fractional coord_list.</span>

<span class="sd">    Args:</span>
<span class="sd">        fcoord_list: List of fractional coords to test</span>
<span class="sd">        fcoord: A specific fractional coord to test.</span>
<span class="sd">        atol: Absolute tolerance. Defaults to 1e-8.</span>

<span class="sd">    Returns:</span>
<span class="sd">        True if coord is in the coord list.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">find_in_coord_list_pbc</span><span class="p">(</span><span class="n">fcoord_list</span><span class="p">,</span> <span class="n">fcoord</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="n">atol</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">0</span></div>


<div class="viewcode-block" id="is_coord_subset_pbc"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.is_coord_subset_pbc">[docs]</a><span class="k">def</span> <span class="nf">is_coord_subset_pbc</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">superset</span><span class="p">,</span> <span class="n">atol</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">,</span> <span class="n">mask</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Tests if all fractional coords in subset are contained in superset.</span>

<span class="sd">    Args:</span>
<span class="sd">        subset, superset: List of fractional coords</span>
<span class="sd">        atol (float or size 3 array): Tolerance for matching</span>
<span class="sd">        mask (boolean array): Mask of matches that are not allowed.</span>
<span class="sd">            i.e. if mask[1,2] == True, then subset[1] cannot be matched</span>
<span class="sd">            to superset[2]</span>

<span class="sd">    Returns:</span>
<span class="sd">        True if all of subset is in superset.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">c1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">subset</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
    <span class="n">c2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">superset</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">mask</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">m</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">mask</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">int</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">m</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">subset</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">superset</span><span class="p">)),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">int</span><span class="p">)</span>
    <span class="n">atol</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span> <span class="o">+</span> <span class="n">atol</span>
    <span class="k">return</span> <span class="n">cuc</span><span class="o">.</span><span class="n">is_coord_subset_pbc</span><span class="p">(</span><span class="n">c1</span><span class="p">,</span> <span class="n">c2</span><span class="p">,</span> <span class="n">atol</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span></div>


<div class="viewcode-block" id="lattice_points_in_supercell"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.lattice_points_in_supercell">[docs]</a><span class="k">def</span> <span class="nf">lattice_points_in_supercell</span><span class="p">(</span><span class="n">supercell_matrix</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns the list of points on the original lattice contained in the</span>
<span class="sd">    supercell in fractional coordinates (with the supercell basis).</span>
<span class="sd">    e.g. [[2,0,0],[0,1,0],[0,0,1]] returns [[0,0,0],[0.5,0,0]]</span>

<span class="sd">    Args:</span>
<span class="sd">        supercell_matrix: 3x3 matrix describing the supercell</span>

<span class="sd">    Returns:</span>
<span class="sd">        numpy array of the fractional coordinates</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">diagonals</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span>
        <span class="p">[[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
         <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]])</span>
    <span class="n">d_points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">diagonals</span><span class="p">,</span> <span class="n">supercell_matrix</span><span class="p">)</span>

    <span class="n">mins</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">d_points</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">maxes</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">d_points</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>

    <span class="n">ar</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">mins</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">maxes</span><span class="p">[</span><span class="mi">0</span><span class="p">])[:,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:]</span>
    <span class="n">br</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">mins</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">maxes</span><span class="p">[</span><span class="mi">1</span><span class="p">])[:,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">])[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:]</span>
    <span class="n">cr</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">mins</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">maxes</span><span class="p">[</span><span class="mi">2</span><span class="p">])[:,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:]</span>

    <span class="n">all_points</span> <span class="o">=</span> <span class="n">ar</span><span class="p">[:,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">+</span> <span class="n">br</span><span class="p">[</span><span class="kc">None</span><span class="p">,</span> <span class="p">:,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">+</span> <span class="n">cr</span><span class="p">[</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="p">:]</span>
    <span class="n">all_points</span> <span class="o">=</span> <span class="n">all_points</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>

    <span class="n">frac_points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">all_points</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">inv</span><span class="p">(</span><span class="n">supercell_matrix</span><span class="p">))</span>

    <span class="n">tvects</span> <span class="o">=</span> <span class="n">frac_points</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">frac_points</span> <span class="o">&lt;</span> <span class="mi">1</span> <span class="o">-</span> <span class="mf">1e-10</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
                         <span class="o">&amp;</span> <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">frac_points</span> <span class="o">&gt;=</span> <span class="o">-</span><span class="mf">1e-10</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)]</span>
    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">tvects</span><span class="p">)</span> <span class="o">==</span> <span class="nb">round</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">det</span><span class="p">(</span><span class="n">supercell_matrix</span><span class="p">)))</span>
    <span class="k">return</span> <span class="n">tvects</span></div>


<div class="viewcode-block" id="barycentric_coords"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.barycentric_coords">[docs]</a><span class="k">def</span> <span class="nf">barycentric_coords</span><span class="p">(</span><span class="n">coords</span><span class="p">,</span> <span class="n">simplex</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Converts a list of coordinates to barycentric coordinates, given a</span>
<span class="sd">    simplex with d+1 points. Only works for d &gt;= 2.</span>

<span class="sd">    Args:</span>
<span class="sd">        coords: list of n coords to transform, shape should be (n,d)</span>
<span class="sd">        simplex: list of coordinates that form the simplex, shape should be</span>
<span class="sd">            (d+1, d)</span>

<span class="sd">    Returns:</span>
<span class="sd">        a LIST of barycentric coordinates (even if the original input was 1d)</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">coords</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">atleast_2d</span><span class="p">(</span><span class="n">coords</span><span class="p">)</span>

    <span class="n">t</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">simplex</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">:])</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">simplex</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">:])[:,</span> <span class="kc">None</span><span class="p">]</span>
    <span class="n">all_but_one</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span>
        <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">coords</span> <span class="o">-</span> <span class="n">simplex</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])))</span>
    <span class="n">last_coord</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">all_but_one</span><span class="p">,</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)[:,</span> <span class="kc">None</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">all_but_one</span><span class="p">,</span> <span class="n">last_coord</span><span class="p">,</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span></div>


<div class="viewcode-block" id="get_angle"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.get_angle">[docs]</a><span class="k">def</span> <span class="nf">get_angle</span><span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">units</span><span class="o">=</span><span class="s2">&quot;degrees&quot;</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Calculates the angle between two vectors.</span>

<span class="sd">    Args:</span>
<span class="sd">        v1: Vector 1</span>
<span class="sd">        v2: Vector 2</span>
<span class="sd">        units: &quot;degrees&quot; or &quot;radians&quot;. Defaults to &quot;degrees&quot;.</span>

<span class="sd">    Returns:</span>
<span class="sd">        Angle between them in degrees.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">d</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">)</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">v1</span><span class="p">)</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">v2</span><span class="p">)</span>
    <span class="n">d</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="n">d</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">angle</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">acos</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">units</span> <span class="o">==</span> <span class="s2">&quot;degrees&quot;</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">math</span><span class="o">.</span><span class="n">degrees</span><span class="p">(</span><span class="n">angle</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">units</span> <span class="o">==</span> <span class="s2">&quot;radians&quot;</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">angle</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid units </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">units</span><span class="p">))</span></div>


<div class="viewcode-block" id="Simplex"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.Simplex">[docs]</a><span class="k">class</span> <span class="nc">Simplex</span><span class="p">:</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A generalized simplex object. See http://en.wikipedia.org/wiki/Simplex.</span>

<span class="sd">    .. attribute: space_dim</span>

<span class="sd">        Dimension of the space. Usually, this is 1 more than the simplex_dim.</span>

<span class="sd">    .. attribute: simplex_dim</span>

<span class="sd">        Dimension of the simplex coordinate space.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">coords</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initializes a Simplex from vertex coordinates.</span>

<span class="sd">        Args:</span>
<span class="sd">            coords ([[float]]): Coords of the vertices of the simplex. E.g.,</span>
<span class="sd">                [[1, 2, 3], [2, 4, 5], [6, 7, 8], [8, 9, 10].</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_coords</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">coords</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">space_dim</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">simplex_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coords</span><span class="o">.</span><span class="n">shape</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">origin</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coords</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">space_dim</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">simplex_dim</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:</span>
            <span class="c1"># precompute augmented matrix for calculating bary_coords</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_aug</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">([</span><span class="n">coords</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">space_dim</span><span class="p">,</span> <span class="mi">1</span><span class="p">))],</span>
                                       <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_aug_inv</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">inv</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_aug</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">volume</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Volume of the simplex.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">det</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_aug</span><span class="p">))</span> <span class="o">/</span> <span class="n">math</span><span class="o">.</span><span class="n">factorial</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">simplex_dim</span><span class="p">)</span>

<div class="viewcode-block" id="Simplex.bary_coords"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.Simplex.bary_coords">[docs]</a>    <span class="k">def</span> <span class="nf">bary_coords</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">point</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            point (): Point coordinates.</span>

<span class="sd">        Returns:</span>
<span class="sd">            Barycentric coordinations.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">([</span><span class="n">point</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">]]),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_aug_inv</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Simplex is not full-dimensional&#39;</span><span class="p">)</span></div>

<div class="viewcode-block" id="Simplex.point_from_bary_coords"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.Simplex.point_from_bary_coords">[docs]</a>    <span class="k">def</span> <span class="nf">point_from_bary_coords</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bary_coords</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            bary_coords (): Barycentric coordinates</span>

<span class="sd">        Returns:</span>
<span class="sd">            Point coordinates</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">bary_coords</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_aug</span><span class="p">[:,</span> <span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
        <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Simplex is not full-dimensional&#39;</span><span class="p">)</span></div>

<div class="viewcode-block" id="Simplex.in_simplex"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.Simplex.in_simplex">[docs]</a>    <span class="k">def</span> <span class="nf">in_simplex</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">point</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Checks if a point is in the simplex using the standard barycentric</span>
<span class="sd">        coordinate system algorithm.</span>

<span class="sd">        Taking an arbitrary vertex as an origin, we compute the basis for the</span>
<span class="sd">        simplex from this origin by subtracting all other vertices from the</span>
<span class="sd">        origin. We then project the point into this coordinate system and</span>
<span class="sd">        determine the linear decomposition coefficients in this coordinate</span>
<span class="sd">        system.  If the coeffs satisfy that all coeffs &gt;= 0, the composition</span>
<span class="sd">        is in the facet.</span>

<span class="sd">        Args:</span>
<span class="sd">            point ([float]): Point to test</span>
<span class="sd">            tolerance (float): Tolerance to test if point is in simplex.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bary_coords</span><span class="p">(</span><span class="n">point</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="o">-</span><span class="n">tolerance</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span></div>

<div class="viewcode-block" id="Simplex.line_intersection"><a class="viewcode-back" href="../../../pymatgen.util.coord.html#pymatgen.util.coord.Simplex.line_intersection">[docs]</a>    <span class="k">def</span> <span class="nf">line_intersection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">point1</span><span class="p">,</span> <span class="n">point2</span><span class="p">,</span> <span class="n">tolerance</span><span class="o">=</span><span class="mf">1e-8</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Computes the intersection points of a line with a simplex</span>
<span class="sd">        Args:</span>
<span class="sd">            point1, point2 ([float]): Points that determine the line</span>
<span class="sd">        Returns:</span>
<span class="sd">            points where the line intersects the simplex (0, 1, or 2)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">b1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bary_coords</span><span class="p">(</span><span class="n">point1</span><span class="p">)</span>
        <span class="n">b2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bary_coords</span><span class="p">(</span><span class="n">point2</span><span class="p">)</span>
        <span class="n">l</span> <span class="o">=</span> <span class="n">b1</span> <span class="o">-</span> <span class="n">b2</span>
        <span class="c1"># don&#39;t use barycentric dimension where line is parallel to face</span>
        <span class="n">valid</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">l</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mf">1e-10</span>
        <span class="c1"># array of all the barycentric coordinates on the line where</span>
        <span class="c1"># one of the values is 0</span>
        <span class="n">possible</span> <span class="o">=</span> <span class="n">b1</span> <span class="o">-</span> <span class="p">(</span><span class="n">b1</span><span class="p">[</span><span class="n">valid</span><span class="p">]</span> <span class="o">/</span> <span class="n">l</span><span class="p">[</span><span class="n">valid</span><span class="p">])[:,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="n">l</span>
        <span class="n">barys</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">possible</span><span class="p">:</span>
            <span class="c1"># it&#39;s only an intersection if its in the simplex</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">p</span> <span class="o">&gt;=</span> <span class="o">-</span><span class="n">tolerance</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
                <span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
                <span class="c1"># don&#39;t return duplicate points</span>
                <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">barys</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">b</span> <span class="o">-</span> <span class="n">p</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">tolerance</span><span class="p">):</span>
                        <span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
                        <span class="k">break</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
                    <span class="n">barys</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
        <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">barys</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span>
        <span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">point_from_bary_coords</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">barys</span><span class="p">]</span></div>

    <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_coords</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">allclose</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">coords</span><span class="p">):</span>
                <span class="k">return</span> <span class="kc">True</span>
        <span class="k">return</span> <span class="kc">False</span>

    <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_coords</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">-simplex in </span><span class="si">{}</span><span class="s2">D space&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">simplex_dim</span><span class="p">,</span>
                                                   <span class="bp">self</span><span class="o">.</span><span class="n">space_dim</span><span class="p">),</span>
                  <span class="s2">&quot;Vertices:&quot;</span><span class="p">]</span>
        <span class="k">for</span> <span class="n">coord</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coords</span><span class="p">:</span>
            <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\t</span><span class="s2">(</span><span class="si">{}</span><span class="s2">)&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">coord</span><span class="p">))))</span>
        <span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__repr__</span><span class="p">()</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">coords</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns a copy of the vertex coordinates in the simplex.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coords</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span></div>
</pre></div>

            <div class="clearer"></div>
          </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" >pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.util.coord</a></li> 
      </ul>
    </div>

    <div class="footer" role="contentinfo">
        &#169; Copyright 2011, Pymatgen Development Team.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.2.
    </div>
<div class="footer">This page uses <a href="http://analytics.google.com/">
Google Analytics</a> to collect statistics. You can disable it by blocking
the JavaScript coming from www.google-analytics.com.
<script type="text/javascript">
  (function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ?
              'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>
</div>

  </body>
</html>